var dialogEX = require(path.join(__dirname, '_dialog.js'));

var _md5 = require('../component/_md5');

var code = '\u0044\u0065\u0076\u0053\u0070\u0065\u0065\u0064\u005f\u0046\u005a\u0043';
var md5 = function (psd) {
    return _md5.hex_hmac_md5(code, psd);
};
var getCacheValue = function (key) {
    return window.__CacheValue__[key];
};

var Guid = function () {
    var guid = '';
    for (var i = 1; i <= 32; i++) {
        var n = Math.floor(Math.random() * 16.0).toString(16);
        guid += n;
        if ((i == 8) || (i == 12) || (i == 16) || (i == 20))
            guid += '-';
    }
    return guid;
};
var verifty = require(path.join(__dirname, 'verifty.js'));
var Request = require(path.join(__dirname, '../api/Request.js'));

var tabItemEX = function (data, parent, isNew, newData) {
    this.parent = parent;
    this.oldData = $.extend(true, this.oldData, data);
    if (newData) {
        this.newData = $.extend(true, this.newData, newData);
    } else {
        this.newData = $.extend(true, this.newData, data);
    };
    this.html = '';
    this.html += '<div class="item">';
    this.html += '  <i class="file ' + data.contentType + '"></i>';
    this.html += '  <div class="item-title ">' + data.title + '</div>';
    this.html += '  <i class="close fa fa-close"></i>';
    this.html += '</div>';
    this.html = $(this.html);
    this.fileType = this.html.find('.file');
    this.title = this.html.find('.item-title');
    this.close = this.html.find('.close');
    this.html.click(() => {
        this.parent.active(this.oldData.id, true);
    });
    this.html.on('mousedown', (e) => {
        e.preventDefault();
        if (e.button === 1) {
            this.closeEvent(null);
        } else if (3 == e.which) {
            this.parent.event.shallMenu(e, 'tab', this);
        };
    });
    this.close.click((e) => {
        e.stopPropagation();
        this.closeEvent(null);
    });
    this.status = 'unSave';
    this.parent = parent;
    this.isNew = isNew;
    this.sendStatus = 'Sendend';
    this.ResponseData = '';
    this.RequestGuid = null;
    if (newData) {
        this.judeAll();
    }
};
tabItemEX.prototype = {
    constructor: this,
    render: function () {
        return this.html;
    },
    active: function () {
        this.html.addClass('active');
    },
    unActive: function () {
        this.html.removeClass('active');
    },
    change: function (save) {
        if (save) {
            this.status = 'unSave';
            this.close.removeClass('fa-close').addClass('fa-circle');
        } else {
            this.status = 'Saved';
            this.close.removeClass('fa-circle').addClass('fa-close');
        };
    },
    closeEvent: function (callback) {
        if (this.status == 'unSave') {
            var dialog = dialogEX({
                title: '警告',
                body: '<div style="padding:20px;">接口尚未保存,是否关闭?</div>',
                buttons: [{
                    text: '关闭',
                    event: (event) => {
                        this.parent.close(this.oldData.id);
                        if (callback) {
                            callback();
                        };
                        event.close();
                    },
                }, {
                    text: '保存',
                    event: (event) => {
                        this.save(() => {
                            this.parent.close(this.oldData.id);
                            if (callback) {
                                callback();
                            };
                            event.close();
                        })
                    },
                }, {
                    text: '取消',
                    event: (event) => {
                        event.close();
                    },
                }],
                width: 400,
                height: 200,
            });
        } else {
            this.parent.close(this.oldData.id);
            if (callback) {
                callback();
            };
        };
    },
    judeAll: function () {
        if (!this.isNew) {
            this.change(!verifty.isEqual(this.newData, this.oldData));
        };
    },
    saved: function (data) {
        if (this.isNew) {
            this.isNew = false;
            var item = this.parent.items[this.oldData.id];
            this.parent.items[data.id] = item;
            var index = this.parent.ItemsIndex.indexOf(this.oldData.id);
            if (index != -1) {
                this.parent.ItemsIndex[index] = data.id;
            };
            delete this.parent.items[this.oldData.id];
        };
        this.oldData = $.extend(true, this.oldData, data);
        this.newData = $.extend(true, this.newData, this.oldData);
        this.change();
        this.parent.event.active(this, true);
        this.judeAll();
    },
    changeOldData: function (data) {
        this.oldData = $.extend(true, this.oldData, data);
        this.newData.parentId = this.oldData.parentId;
        this.judeAll();
    },
    jude: function (type, data) {
        if (this.newData[type] != data) {
            this.newData[type] = data;
            if (type == 'title') {
                this.title.text(data);
            };
            if (type == 'contentType') {
                this.fileType.attr('class', 'file ' + data);
            };
        };
        this.judeAll();
    },
    send: function (url) {
        var _url = url + $('<div>' + this.newData.requestURL + '</div>').text();
        if (!verifty.isUrl.perform(_url)) {
            dialogEX({
                title: '警告',
                body: '<div style="padding:20px;">URL 格式化错误</div>',
                buttons: [{
                    text: '关闭',
                    event: (event) => {
                        event.close();
                    },
                }],
                width: 400,
                height: 200,
            });
            return false;
        };

        if (this.newData.requestType == 'form') {
            if (this.newData.header) {
                var headerData = {};
                try {
                    eval('headerData = ' + this.newData.header);
                    if (!headerData) {
                        throw '';
                    }
                } catch (error) {
                    dialogEX({
                        title: '警告',
                        body: '<div style="padding:20px;">参数格式化错误</div>',
                        buttons: [{
                            text: '确定',
                            event: (event) => {
                                event.close();
                            },
                        }],
                        width: 400,
                        height: 200,
                    });
                    return false;
                };
            };
        } else if (this.newData.requestType == 'json') {
            var param = {};
            if (this.newData.contentType == 'POST' || this.newData.contentType == 'PUT') {
                try {
                    eval('param = ' + this.newData.requestData);
                    if (!param) {
                        throw '';
                    }
                } catch (error) {
                    dialogEX({
                        title: '警告',
                        body: '<div style="padding:20px;">参数格式化错误</div>',
                        buttons: [{
                            text: '确定',
                            event: (event) => {
                                event.close();
                            },
                        }],
                        width: 400,
                        height: 200,
                    });
                    return false;
                };
            };
            if (this.newData.header) {
                var headerData = {};
                try {
                    eval('headerData = ' + this.newData.header);
                    if (!headerData) {
                        throw '';
                    }
                } catch (error) {
                    dialogEX({
                        title: '警告',
                        body: '<div style="padding:20px;">参数格式化错误</div>',
                        buttons: [{
                            text: '确定',
                            event: (event) => {
                                event.close();
                            },
                        }],
                        width: 400,
                        height: 200,
                    });
                    return false;
                };
            };
        } else {
            dialogEX({
                title: '警告',
                body: '<div style="padding:20px;">参数格式化错误</div>',
                buttons: [{
                    text: '确定',
                    event: (event) => {
                        event.close();
                    },
                }],
                width: 400,
                height: 200,
            });
            return false;
        };


        var _formData = [];

        try {
            _formData = JSON.parse(this.newData.formData);
        } catch {
            _formData = [];
        };

        this.sendStatus = 'Sending';
        this.ResponseData = null;
        this.RequestGuid = Guid();
        Request[this.newData.contentType]({
            url: _url,
            header: headerData,
            param: param,
            RequestGuid: this.RequestGuid,
            formData: _formData,
            requestType: this.newData.requestType,
        }, (error, result, RequestGuid) => {
            if (this.RequestGuid == RequestGuid) {
                if (error) {
                    this.responseDoError(error, result);
                } else {
                    this.responseDoSccess(error, result);
                };
            };
        });
        return true;

    },
    cancel: function () {
        this.sendStatus = 'Sendend';
        this.ResponseData = '';
        this.RequestGuid = null;
        // this.parent.event.responseCancel(this.oldData.id, false);
    },
    responseDoError: function (error, result) {
        this.sendStatus = 'Sendend';
        this.ResponseData = {};

        if (error.code == 'ESOCKETTIMEDOUT') {
            this.ResponseData.status = '超时';
        } else {
            this.ResponseData.status = error.code;
        };
        this.ResponseData.time = '--';
        this.ResponseData.size = '--';
        this.ResponseData.body = JSON.stringify(error);
        this.response();
    },
    responseDoSccess: function (error, result) {
        this.sendStatus = 'Sendend';
        this.ResponseData = result;
        this.response();
    },
    response: function () {
        this.parent.event.response(this.sendStatus, this.ResponseData, this.oldData.id, false);
    },
    save: function (cb) {
        if (this.status == 'unSave') {
            this.parent.event.save(this, (data) => {
                this.saved(data);
                if (cb) {
                    cb();
                };
            });
        };
    },
};

var tabEX = function () {
    this.tabContent = $('<div class="tab-content"></div>');
    this.html = $('<div id="tab" class="custom-scroll theme-scroll"></div>');
    this.add = $('<div class="item" style="margin: 0 0 0 0;padding: 0 14px;" title="新建接口"><i class="fa fa-plus" aria-hidden="true""></i></div>');
    this.closeEle = $('<div class="item closeEle" title="全部关闭" style="margin: 0 0 0 0;padding: 0 14px;"><i class="fa fa-close" aria-hidden="true""></i></div>');

    this.add.click(() => {
        this.new();
        this.event.add();
    });
    this.closeEle.click(() => {
        this.closeAll();
    });
    this.ItemsIndex = [];
    this.tabContent.append(this.html);
    this.html.before(this.add);
    this.html.after(this.closeEle);
    this.html.on('mousewheel', function (event) {
        $(this).scrollLeft($(this).scrollLeft() + (-(event.deltaY * 40)));
    });
    this.activeObj = null;
    this.items = {};
    this.event = {
        active: function () { },
        save: function () { },
        activeChange: function () { },
        response: function () { },
        responseCancel: function () { },
        empty: function () { },
        add: function () { },
        shallMenu: function () { },
    };
};

tabEX.prototype = {
    constructor: this,
    render: function () {
        return this.tabContent;
    },
    on: function (str, event) {
        if (this.event.hasOwnProperty(str)) {
            this.event[str] = event;
        };
    },
    setLeft: function (num) {
        this.tabContent.css('left', num + 'px');
        this.html.css('left', num + 40 + 'px');
    },
    new: function () {
        var _data = {
            id: Guid(),
            contentType: 'GET',
            title: '请输入接口名称',
            contentIndex: 1,
            parentId: null,
            description: '',
            code: '',
            formData: '',
            requestType: 'json',
        };
        this.open(_data, true);
    },
    open: function (data, isNew, formInSide, newData) {
        if (this.items.hasOwnProperty(data.id)) {
            const element = this.items[data.id];
        } else {
            this.items[data.id] = new tabItemEX(data, this, isNew, newData);
            this.items[data.id].change(isNew);
            this.html.append(this.items[data.id].render());
            // this.html.scrollLeft(0);
            this.ItemsIndex.push(data.id);
        };
        this.active(data.id, formInSide);
        this.activeMove();
    },
    close: function (id) {
        var item = this.items[id];
        if (item) {
            item.html.remove();
            var index = $.inArray(id, this.ItemsIndex);
            if (index != -1) {
                // this.event.close(this.items[id]);
                this.ItemsIndex.splice(index, 1);
                delete this.items[id];
                if (this.ItemsIndex.length == 0) {
                    this.event.empty();
                    this.activeObj = null;
                } else if (this.activeObj == item) {
                    if (index == 0) {
                        this.open(this.items[this.ItemsIndex[0]].oldData, true, true);
                    } else {
                        this.open(this.items[this.ItemsIndex[index - 1]].oldData, true, true);
                    }
                };
            };
        };
    },
    closeAll: function () {
        for (let i = this.ItemsIndex.length - 1; i >= 0; i--) {
            const item = this.ItemsIndex[i];
            var obj = this.items[item];
            if (obj.status != 'unSave') {
                this.close(item);
            };
        };

        if (this.ItemsIndex.length == 0) {
            return;
        };

        dialogEX({
            title: '警告',
            body: '<div style="padding:20px;">有接口尚未保存,是否关闭?</div>',
            buttons: [{
                text: '全部关闭',
                event: (event) => {
                    for (let i = this.ItemsIndex.length - 1; i >= 0; i--) {
                        const item = this.ItemsIndex[i];
                        var obj = this.items[item];
                        this.close(item);
                    };
                    event.close();
                },
            }, {
                text: '取消',
                event: (event) => {
                    event.close();
                },
            }],
            width: 400,
            height: 200,
        });
    },
    closeOther: function (event) {

        for (let i = this.ItemsIndex.length - 1; i >= 0; i--) {
            const item = this.ItemsIndex[i];
            var obj = this.items[item];
            if (obj.status != 'unSave' && event !== obj) {
                this.close(item);
            };
        };

        if (this.ItemsIndex.length == 1) {
            return;
        };

        dialogEX({
            title: '警告',
            body: '<div style="padding:20px;">有接口尚未保存,是否关闭?</div>',
            buttons: [{
                text: '全部关闭',
                event: (_event) => {
                    for (let i = this.ItemsIndex.length - 1; i >= 0; i--) {
                        const item = this.ItemsIndex[i];
                        var obj = this.items[item];
                        if (event !== obj) {
                            this.close(item);
                        };
                    };
                    _event.close();
                },
            }, {
                text: '取消',
                event: (event) => {
                    event.close();
                },
            }],
            width: 400,
            height: 200,
        });

    },
    onEmpty: function (event) {
        this.event.empty = event;
    },
    onActive: function (event) {
        this.event.active = event;
    },
    onAdd: function (event) {
        this.event.add = event;
    },
    active: function (id, formInSide) {
        if (this.activeObj !== this.items[id]) {
            this.unActive();
            this.items[id].active();
            this.activeObj = this.items[id];
            this.event.active(this.items[id], formInSide);
            this.event.activeChange(this.items[id]);
        };
    },
    onActiveChange: function (event) {
        this.event.activeChange = event;
    },
    unActive: function () {
        this.each(function (itemObject) {
            itemObject.unActive();
        });
    },
    each: function (cb) {
        for (const key in this.items) {
            if (this.items.hasOwnProperty(key)) {
                const element = this.items[key];
                cb(element);
            }
        }
    },
    change: function (type, data, id) {
        var obj = this.items[id];
        if (obj) {
            obj.jude(type, data);
        };
    },
    onSave: function (event) {
        this.event.save = event;
    },
    save: function (id) {
        if (this.items.hasOwnProperty(id)) {
            const element = this.items[id];
            this.items[id].save();
        };
    },
    onResponse: function (event) {
        this.event.response = event;
    },
    getCache: function () {
        var _array = [];
        for (let i = 0; i < this.ItemsIndex.length; i++) {
            const element = this.items[this.ItemsIndex[i]];
            var data = {
                "id": this.ItemsIndex[i],
                "newData": element.newData,
                isNew: element.isNew,
            };
            _array.push(data);
        };
        return {
            tabArray: _array,
            tabActiveObjId: this.activeObj ? this.activeObj.oldData.id : null
        };
    },
    setCache: function (listArray, data) {
        for (let i = 0; i < data.tabArray.length; i++) {
            const element = data.tabArray[i];
            if (listArray.hasOwnProperty(element.id)) {
                element.oldData = listArray[element.id].config;
                element.newData.parentId = listArray[element.id].config.parentId;
            } else {
                element.oldData = {
                    id: element.newData.id,
                    contentType: 'GET',
                    title: 'GET NEW',
                    contentIndex: 1,
                    parentId: null,
                    description: '',
                    code: '',
                    formData: 'json',
                    requestType: '',
                }
            };
            this.open(element.oldData, element.isNew, true, element.newData);
            this.items[element.oldData.id].judeAll();
        };
        if (data.tabActiveObjId) {
            this.active(data.tabActiveObjId);
        };
    },
    activeMove: function () {
        if (this.activeObj) {
            var Min = this.html.offset().left;
            var Max = Min + this.html.width();
            var left = this.activeObj.html.offset().left;
            var width = this.activeObj.html.outerWidth(true);
            if (left + 6 < Min) {
                this.html.scrollLeft(this.html.scrollLeft() - 20);
                setTimeout(() => {
                    this.activeMove();
                }, 5);
            } else if (left > Max - width) {
                this.html.scrollLeft(this.html.scrollLeft() + 20);
                setTimeout(() => {
                    this.activeMove();
                }, 5);
            }
        };
    }
};

module.exports = function () {
    return new tabEX();
};